package com.samp.bblock.seckill.service;

import com.samp.bblock.core.exception.DaoException;
import com.samp.bblock.core.exception.ServiceException;
import com.samp.bblock.seckill.dao.SeckillInfoDAO;
import com.samp.bblock.seckill.dto.SeckillDTO;
import com.samp.bblock.seckill.dto.SeckillDetailDTO;
import com.samp.bblock.util.RandomUtils;
import com.samp.bblock.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("seckillService")
public class SeckillService {

    @Resource
    private SeckillInfoDAO seckillInfoDAO;

    private static final Logger logger = LoggerFactory.getLogger(SeckillService.class);

    public SeckillDTO seckill(SeckillDTO paramDTO) throws ServiceException{
        if(StringUtils.isBlank(paramDTO.getSeckillId()) ||
                StringUtils.isBlank(paramDTO.getUserName()) ){
            throw new ServiceException("参数为空，无法秒杀");
        }
        SeckillDTO seckillDTO = getSeckillInfo(paramDTO.getSeckillId());
        if( seckillDTO == null ){
            logger.info("不在秒杀时间内。");
            return null;
        }
        float seckillAmount = getSeckillAmount(seckillDTO);
        SeckillDetailDTO detailDTO = new SeckillDetailDTO();
        detailDTO.setSeckillId(paramDTO.getSeckillId());
        detailDTO.setUserName(paramDTO.getUserName());
        detailDTO.setSeckillAmount(seckillAmount);
        if( seckillAmount == 0 ){
            detailDTO.setSeckillStatus(3);
        }else {
            detailDTO.setSeckillStatus(1);
            seckillDTO.setSeckillAmount(seckillAmount);
            seckillDTO.setRemainAmount(seckillDTO.getRemainAmount()-seckillAmount);
            int recordModi = saveSeckillDetailInfo(seckillDTO);
            if( recordModi != 1 ){
                detailDTO.setSeckillStatus(2);
                logger.info("用户"+detailDTO.getUserName()+"秒杀失败。");
            }else {
                logger.info("用户"+detailDTO.getUserName()+"秒杀成功。金额："+seckillAmount);
            }
        }
        saveSeckillDetailInfo(detailDTO);
        return seckillDTO;
    }

    private float getSeckillAmount(SeckillDTO seckillDTO){
        if( seckillDTO.getRemainUser() == null || seckillDTO.getRemainUser().intValue() == 0
                || seckillDTO.getRemainAmount() == null || seckillDTO.getRemainAmount().equals(new Float(0.0f)) ){
            return 0;
        }
        if( seckillDTO.getRemainUser().intValue() == 1 ){
            return seckillDTO.getRemainAmount();
        }
        float minAmount = seckillDTO.getRemainAmount()/seckillDTO.getRemainUser()/10;
        float maxAmount = seckillDTO.getRemainAmount()*0.4f;
        Integer randomAmount = RandomUtils.getRandomInt(new Float(minAmount*100).intValue(),
                new Float(maxAmount*100).intValue());
        return randomAmount.intValue()*1.0f/100;
    }

    private SeckillDTO getSeckillInfo(String seckilllId) throws ServiceException{
        try {
            return seckillInfoDAO.querySeckillBaseInfo(seckilllId);
        }catch (DaoException e){
            throw new ServiceException("error when query seckill base info,seckillId="+seckilllId, e);
        }
    }

    private void saveSeckillDetailInfo(SeckillDetailDTO detailDTO)throws ServiceException{
        try {
            seckillInfoDAO.insertSeckillDetailInfo(detailDTO);
        }catch (DaoException e){
            throw new ServiceException("error when saveSeckillDetailInfo,detailDTO="+detailDTO, e);
        }
    }

    private int saveSeckillDetailInfo(SeckillDTO seckillDTO)throws ServiceException{
        try {
           return seckillInfoDAO.updateSeckillBaseInfo(seckillDTO);
        }catch (DaoException e){
            throw new ServiceException("error when updateSeckillBaseInfo,seckillDTO="+seckillDTO, e);
        }
    }
}
